package com.example.jvm_monitor;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

@SpringBootApplication
@RestController
public class JvmMonitorApplication {

    public static void main(String[] args) {
        SpringApplication.run(JvmMonitorApplication.class, args);
    }

    @GetMapping("/while")
    public void cycle() {
        while (true) {

        }
    }

    @GetMapping("/triggerGc")
    public void triggerGc() {
        while (true) {
            new User(new Random().toString());
        }
    }

    @GetMapping("/triggerOOM")
    public void triggerOOM() {
        List<byte[]> list = new ArrayList<>();

        while (true) {
            byte[] bytes = new byte[1024 * 1024];
            list.add(bytes);
        }
    }

    @GetMapping("/triggerOOM2")
    public void triggerOOM2() {
        List<User> users = new ArrayList<>();

        while (true) {
            users.add(new User(new Random().toString()));
        }
    }

    @GetMapping("/triggerDeadLock")
    public void triggerDeadLock() {
        Object o1 = new Object();
        Object o2 = new Object();

        Thread t1 = new Thread(() -> {
            synchronized (o1) {
                System.out.println("线程1获得o1锁，尝试获得o2锁...");

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

                synchronized (o2) {
                    System.out.println("线程1获得o2锁");
                }
            }
        });

        Thread t2 = new Thread(() -> {
            synchronized (o2) {
                System.out.println("线程2获得o2锁，尝试获得o1锁...");

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

                synchronized (o1) {
                    System.out.println("线程2获得o1锁");
                }
            }
        });

        t1.start();
        t2.start();
    }
}
